package com.jzo2o.health.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.listener.AnalysisEventListenerImpl;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.model.excel.ReservationImportData;
import com.jzo2o.health.service.IReservationSettingService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.swing.text.DateFormatter;
import java.text.DateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 预约设置 服务实现类
 * </p>
 *
 * @author author
 * @since 2024-12-13
 */
@Service
@Slf4j
public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettingMapper, ReservationSetting> implements IReservationSettingService {

    /**
     * 按月查询预约设置
     *
     * @param date
     * @return
     */
    @Override
    public List<ReservationSettingResDTO> getReservationSettingByMonth(String date) {
        if (ObjectUtils.isEmpty(date)) {
            throw new ForbiddenOperationException("参数错误");
        }
        List<ReservationSetting> list = this.lambdaQuery()
                .likeRight(ReservationSetting::getOrderDate, date)
                .list();
        ArrayList<ReservationSettingResDTO> reservationSettingResDTOS = new ArrayList<>();
        for (ReservationSetting reservationSetting : list) {
            ReservationSettingResDTO reservationSettingResDTO = BeanUtils.copyBean(reservationSetting, ReservationSettingResDTO.class);
            reservationSettingResDTO.setDate(reservationSetting.getOrderDate().toString());
            reservationSettingResDTOS.add(reservationSettingResDTO);
        }
        return reservationSettingResDTOS;
    }

    /**
     * 编辑预约设置
     *
     * @param reservationSettingUpsertReqDTO
     */
    @Override
    public void editNumberByDate(ReservationSettingUpsertReqDTO reservationSettingUpsertReqDTO) {
        if (ObjectUtils.isEmpty(reservationSettingUpsertReqDTO)) {
            throw new ForbiddenOperationException("参数错误");
        }
        ReservationSetting reservationSetting = BeanUtils.copyBean(reservationSettingUpsertReqDTO, ReservationSetting.class);
        //如何日期在表中存在就更新，不存在就插入
        boolean b = this.saveOrUpdate(reservationSetting,
                Wrappers.<ReservationSetting>lambdaQuery()
                        .eq(ReservationSetting::getOrderDate, reservationSetting.getOrderDate())
                        .lt(ReservationSetting::getReservations, reservationSetting.getNumber())
        );
        if (!b) {
            throw new DBException("修改人数小于已预约人数");
        }

    }



    /**
     * 用户按月查询可预约日期
     *
     * @param month
     * @return
     */
    @Override
    public ReservationDateResDTO getReservationDateByMonth(String month) {

        if (ObjectUtils.isEmpty(month)) {
            throw new ForbiddenOperationException("参数错误");
        }
        //select * from reservation_setting where order_date like '2024-12%' and reservation < number
        List<ReservationSetting> list = this.lambdaQuery()
                .select(ReservationSetting::getOrderDate)
                .likeRight(ReservationSetting::getOrderDate, month)
                .apply(" reservations < number ")
                .list();
        List<String> stringList = list.stream().map(x -> x.getOrderDate().toString()).collect(Collectors.toList());
        ReservationDateResDTO reservationDateResDTO = new ReservationDateResDTO(stringList);
        return reservationDateResDTO;
    }

    @Autowired
    private IReservationSettingService owner;
    /**
     * 批量预约设置
     *
     * @param file
     */
    @Override
    public void batchSetting(MultipartFile file) {
        if (ObjectUtils.isEmpty(file)) {
            throw new ForbiddenOperationException("参数错误");
        }
        try {
            EasyExcel.read(file.getInputStream(), ReservationImportData.class, new AnalysisEventListenerImpl(owner)
            ).sheet().doRead();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Autowired
    private ReservationSettingMapper reservationSettingMapper;

    /**
     * 预约人数增加一
     *
     * @param date
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOne(LocalDate date) {
        boolean b = reservationSettingMapper.addOne(date);
        if (!b) {
            throw new DBException("预约人数增加失败,人数已达上限");
        }
    }

    /**
     * 预约人数减少一
     *
     * @param date
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void subtractOne(LocalDate date) {
        boolean b = reservationSettingMapper.subtractOne(date);
        if (!b) {
            throw new DBException("预约人数增加失败,人数已达上限");
        }
    }
}
